#pragma once
#include <mutex>
namespace wzh
{
	template <class T>
	class Shared_ptr
	{
	public:
		Shared_ptr(T* ptr = nullptr) : _ptr(ptr), _count(nullptr), _mtx(nullptr) 
		{
			_count = new int(1);
			_mtx = new std::mutex;
		}
		Shared_ptr(Shared_ptr& sptr) : _ptr(sptr._ptr), _count(sptr._count), _mtx(sptr._mtx)
		{
			addcount();
		}
		void addcount()
		{
			_mtx->lock()
			(*_count)++;
			_mtx->unlock();
		}
		void subcount()
		{
			bool flag = false;
			_mtx->lock();
			(*_count)--;
			if (_count == 0)
			{
				if(_ptr) delete _ptr;
				delete _count;
				flag = true;
				_ptr = nullptr;
				_count = nullptr;
			}
			_mtx->unlock();
			if (flag) delete _mtx;
		}
		T& operator=(Shared_ptr& sptr)
		{
			if (_ptr != sptr._ptr)
			{
				subcount();
				_ptr = sptr._ptr;
				_count = sptr._count;
				_mtx = sptr._mtx;
				addcount();
			}
			return *this;
		}
		~Shared_ptr()
		{
			subcount();
		}
	private:
		T* _ptr;
		int* _count;
		std::mutex* _mtx;
	};
}